#ifndef REGISTERTYPE_H
#define REGISTERTYPE_H
#include <unordered_map>
#include <string>

//#include <hash_set>
#include <QSet>
#include <functional>
class Helper;

namespace std{
template<typename T>
class hash_set:public QSet<T>{
};
}

extern std::unordered_map<std::string, std::hash_set<void *>> g_mapObjManaged;
extern std::unordered_map<std::string, std::function<Helper*(void*)>> g_mapTypeConstructFunc;

#define STD_ std::

#define STRING string

#define MANAGER_ g_mapObjManaged
#define MANAGER_FUNC g_mapTypeConstructFunc


#define MANAGER(X) MANAGER_[#X]
#define INSERT insert


class Helper
{
protected:
    void *ptr;
public:
    bool isNull(){
        return ptr == nullptr;
    }
};

#define CONSTUCT_FUNC(X)\
    X(void* PTR){\
    MANAGER_FUNC[#X] = [](void* ptr)->Helper*{\
        return (Helper*)(X##Helper(ptr).get());\
    };\
}

#define ManagedCenter(X)\
public: \
    CONSTUCT_FUNC(X)\
    static X* create(){\
    const static STD_ string className = #X; \
    auto _Ptr = new X(); \
   MANAGER(X).INSERT(_Ptr);  \
    return _Ptr; \
}

#define HELPER(X) \
    class X;\
    class X##Helper: public Helper{\
    public:\
    X##Helper(void* _ptr){\
    if (MANAGER_[#X].end() == MANAGER_[#X].find(ptr))\
        ptr = (X*)_ptr;\
    }\
    X* get()const{\
        return (X*)ptr;\
    }\
};
#endif // REGISTERTYPE_H
